home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / bash / bash_110 / mint / bash110s.zoo / bash-1.10 / builtins / set.def < prev    next >
Encoding:
Text File  |  1991-09-05  |  12.6 KB  |  502 lines

  1. This file is set.def, from which is created set.c.
  2. It implements the "set" and "unset" builtins in Bash.
  3.  
  4. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
  5.  
  6. This file is part of GNU Bash, the Bourne Again SHell.
  7.  
  8. Bash is free software; you can redistribute it and/or modify it under
  9. the terms of the GNU General Public License as published by the Free
  10. Software Foundation; either version 1, or (at your option) any later
  11. version.
  12.  
  13. Bash is distributed in the hope that it will be useful, but WITHOUT ANY
  14. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License along
  19. with Bash; see the file COPYING.  If not, write to the Free Software
  20. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. $PRODUCES set.c
  23.  
  24. #include <stdio.h>
  25. #include "../shell.h"
  26. #include "../flags.h"
  27.  
  28. extern int interactive;
  29.  
  30. $BUILTIN set
  31. $FUNCTION set_builtin
  32. $SHORT_DOC set [-aefhknotuvxldH] [arg ...]
  33.     -a  Mark variables which are modified or created for export
  34.     -e  Exit immediately if a command exits with a non-zero status
  35.     -f  Disable file name generation (globbing)
  36.     -h  Locate and remember function commands as functions are
  37.     defined.  Function commands are normally looked up when
  38.     the function is executed
  39.     -k  All keyword arguments are placed in the environment for a
  40.     command, not just those that precede the command name
  41.     -m  Job control is enabled
  42.     -n  Read commands but do not execute them
  43.     -o option-name
  44.     Set the variable corresponding to option-name:
  45.         allexport    same as -a
  46.         braceexpand  the shell will perform brace expansion
  47.         emacs     use an emacs-style line editing interface
  48.         errexit     same as -e
  49.         histexpand     same as -H
  50.         ignoreeof    the shell will not exit upon reading EOF
  51.         monitor      same as -m
  52.         noclobber    disallow redirection to existing files
  53.         noexec       same as -n
  54.         noglob       same as -f
  55.         nohash       same as -d
  56.         notify       notify of job termination immediately
  57.         nounset      same as -u
  58.         verbose      same as -v
  59.         vi           use a vi-style line editing interface
  60.         xtrace       same as -x
  61.     -t  Exit after reading and executing one command
  62.     -u  Treat unset variables as an error when substituting
  63.     -v  Print shell input lines as they are read
  64.     -x  Print commands and their arguments as they are executed
  65.     -l  Save and restore the binding of the NAME in a FOR command.
  66.     -d  Disable the hashing of commands that are looked up for execution.
  67.     Normally, commands are remembered in a hash table, and once
  68.     found, do not have to be looked up again
  69.     -H  Enable ! style history substitution.  This flag is on
  70.     by default.
  71.     -C  If set, disallow existing regular files to be overwritten
  72.     by redirection of output.
  73.  
  74. Using + rather than - causes these flags to be turned off.  The
  75. flags can also be used upon invocation of the shell.  The current
  76. set of flags may be found in $-.  The remaining ARGs are positional
  77. parameters and are assigned, in order, to $1, $2, .. $9.  If no
  78. ARGs are given, all shell variables are printed.
  79. $END
  80.  
  81. /* An a-list used to match long options for set -o to the corresponding
  82.    option letter. */
  83. struct {
  84.   char *name;
  85.   int letter;
  86. } o_options[] = {
  87.   {"allexport",    'a'},
  88.   {"errexit",    'e'},
  89.   {"histexpand",'H'},
  90.   {"monitor",    'm'},
  91.   {"noexec",    'n'},
  92.   {"noglob",    'f'},
  93.   {"nohash",    'd'},
  94.   {"nounset",    'u'},
  95.   {"verbose",    'v'},
  96.   {"xtrace",    'x'},
  97.   {(char *)NULL, 0},
  98. };
  99.  
  100. static void
  101. list_long_opts ()
  102. {
  103.   register int    i;
  104.   char *on = "on", *off = "off";
  105.   extern int noclobber, no_brace_expansion;
  106.   extern SHELL_VAR *find_variable ();
  107.  
  108. #if defined (JOB_CONTROL)
  109.   extern int asynchronous_notification;
  110. #endif /* JOB_CONTROL */
  111.  
  112. #if defined (READLINE)
  113.   extern int rl_editing_mode, no_line_editing;
  114. #endif /* READLINE */
  115.  
  116.   printf ("%-15s\t%s\n", "braceexpand", (no_brace_expansion == 0) ? on : off);
  117.   printf ("%-15s\t%s\n", "noclobber", (noclobber == 1) ? on : off);
  118.  
  119. #if defined (JOB_CONTROL)
  120.   printf ("%-15s\t%s\n", "notify",
  121.       (asynchronous_notification == 1) ? on : off);
  122. #endif /* JOB_CONTROL */
  123.  
  124.   if (find_variable ("ignoreeof") || find_variable ("IGNOREEOF"))
  125.     printf ("%-15s\t%s\n", "ignoreeof", on);
  126.   else
  127.     printf ("%-15s\t%s\n", "ignoreeof", off);
  128.  
  129. #if defined (READLINE)
  130.   if (no_line_editing)
  131.     {
  132.       printf ("%-15s\toff\n", "emacs");
  133.       printf ("%-15s\toff\n", "vi");
  134.     }
  135.   else
  136.     {
  137.       /* Magic.  This code `knows' how readline handles rl_editing_mode. */
  138.       printf ("%-15s\t%s\n", "emacs", (rl_editing_mode == 1) ? on : off);
  139.       printf ("%-15s\t%s\n", "vi", (rl_editing_mode == 0) ? on : off);
  140.     }
  141. #endif /* READLINE */
  142.  
  143.   for (i = 0; o_options[i].name; i++)
  144.     {
  145.       int *on_or_off, zero = 0;
  146.       char name[2];
  147.  
  148.       name[0] = o_options[i].letter;
  149.       name[1] = '\0';
  150.       on_or_off = find_flag (name);
  151.       if (on_or_off == (int *)FLAG_ERROR)
  152.     on_or_off = &zero;
  153.       printf ("%-15s\t%s\n", o_options[i].name, (*on_or_off == 1) ? on : off);
  154.     }
  155. }
  156.  
  157. set_minus_o_option (on_or_off, option_name)
  158.      int on_or_off;
  159.      char *option_name;
  160. {
  161.   extern int no_brace_expansion;
  162.   int option_char = -1;
  163.  
  164.   if (strcmp (option_name, "braceexpand") == 0)
  165.     {
  166.       if (on_or_off == FLAG_ON)
  167.     no_brace_expansion = 0;
  168.       else
  169.     no_brace_expansion = 1;
  170.     }
  171.   else if (strcmp (option_name, "noclobber") == 0)
  172.     {
  173.       if (on_or_off == FLAG_ON)
  174.     bind_variable ("noclobber", "");
  175.       else
  176.     unbind_variable ("noclobber");
  177.       stupidly_hack_special_variables ("noclobber");
  178.     }
  179. #if defined (JOB_CONTROL)
  180.   else if (strcmp (option_name, "notify") == 0)
  181.     {
  182.       if (on_or_off == FLAG_ON)
  183.     bind_variable ("notify", "");
  184.       else
  185.     unbind_variable ("notify");
  186.       stupidly_hack_special_variables ("notify");
  187.     }
  188. #endif /* JOB_CONTROL */
  189.  
  190.   else if (strcmp (option_name, "ignoreeof") == 0)
  191.     {
  192.       unbind_variable ("ignoreeof");
  193.       unbind_variable ("IGNOREEOF");
  194.       if (on_or_off == FLAG_ON)
  195.     bind_variable ("IGNOREEOF", "10");
  196.       stupidly_hack_special_variables ("IGNOREEOF");
  197.     }
  198.  
  199. #if defined (READLINE)
  200.   else if ((strcmp (option_name, "emacs") == 0) ||
  201.        (strcmp (option_name, "vi") == 0))
  202.     {
  203.       extern int no_line_editing;
  204.  
  205.       if (on_or_off == FLAG_ON)
  206.     {
  207.       rl_variable_bind ("editing-mode", option_name);
  208.  
  209.       if (interactive)
  210.         with_input_from_stdin ();
  211.       no_line_editing = 0;
  212.     }
  213.       else
  214.     {
  215.       extern int rl_editing_mode;
  216.       int isemacs = (rl_editing_mode == 1);
  217.       if ((isemacs && strcmp (option_name, "emacs") == 0) ||
  218.           (!isemacs && strcmp (option_name, "vi") == 0))
  219.         {
  220.           if (interactive)
  221.         with_input_from_stream (stdin, "stdin");
  222.           no_line_editing = 1;
  223.         }
  224.       else
  225.         builtin_error ("not in %s editing mode",
  226.                 option_name);
  227.     }
  228.     }
  229. #endif /* READLINE */
  230.   else
  231.     {
  232.       register int i;
  233.       for (i = 0; o_options[i].name; i++)
  234.     {
  235.       if (strcmp (option_name, o_options[i].name) == 0)
  236.         {
  237.           option_char = o_options[i].letter;
  238.           break;
  239.         }
  240.     }
  241.       if (option_char == -1)
  242.     {
  243.       builtin_error ("%s: unknown option name", option_name);
  244.       return (EXECUTION_FAILURE);
  245.     }
  246.       if (change_flag_char (option_char, on_or_off) == FLAG_ERROR)
  247.     {
  248.       bad_option (option_name);
  249.       return (EXECUTION_FAILURE);
  250.     }
  251.     }
  252.     return (EXECUTION_SUCCESS);
  253. }
  254.  
  255. /* Set some flags from the word values in the input list.  If LIST is empty,
  256.    then print out the values of the variables instead.  If LIST contains
  257.    non-flags, then set $1 - $9 to the successive words of LIST. */
  258. set_builtin (list)
  259.      WORD_LIST *list;
  260. {
  261.   int on_or_off, flag_name, force_assignment = 0;
  262.  
  263.   if (!list)
  264.     {
  265.       SHELL_VAR **vars;
  266.  
  267.       vars = all_shell_variables ();
  268.       if (vars)
  269.     {
  270.       print_var_list (vars);
  271.       free (vars);
  272.     }
  273.  
  274.       vars = all_shell_functions ();
  275.       if (vars)
  276.     {
  277.       print_var_list (vars);
  278.       free (vars);
  279.     }
  280.  
  281.       return (EXECUTION_SUCCESS);
  282.     }
  283.  
  284.   /* Check validity of flag arguments. */
  285.   if (*list->word->word == '-' || *list->word->word == '+')
  286.     {
  287.       register char *arg;
  288.       WORD_LIST *save_list = list;
  289.  
  290.       while (list && (arg = list->word->word))
  291.     {
  292.       char s[2];
  293.  
  294.       if (arg[0] != '-' && arg[0] != '+')
  295.         break;
  296.  
  297.       /* `-' or `--' signifies end of flag arguments. */
  298.       if (arg[0] == '-' &&
  299.           (!arg[1] || (arg[1] == '-' && !arg[2])))
  300.         break;
  301.  
  302.       s[1] = '\0';
  303.  
  304.       while (s[0] = *++arg)
  305.         {
  306.           if (find_flag (s) == (int *)FLAG_ERROR && s[0] != 'o')
  307.         {
  308.           bad_option (s);
  309.           return (EXECUTION_FAILURE);
  310.         }
  311.         }
  312.       list = list->next;
  313.     }
  314.       list = save_list;
  315.     }
  316.  
  317.   /* Do the set command.  While the list consists of words starting with
  318.      '-' or '+' treat them as flags, otherwise, start assigning them to
  319.      $1 ... $n. */
  320.   while (list)
  321.     {
  322.       char *string = list->word->word;
  323.  
  324.       /* If the argument is `--' then signal the end of the list and
  325.      remember the remaining arguments. */
  326.       if ((strcmp (string, "--") == 0) || (strcmp (string, "-") == 0))
  327.     {
  328.       list = list->next;
  329.  
  330.       /* `set --' unsets the positional parameters. */
  331.       if (strcmp (string, "--") == 0)
  332.         force_assignment = 1;
  333.  
  334.       /* Until told differently, the old shell behaviour of
  335.          `set - [arg ...]' being equivalent to `set +xv [arg ...]'
  336.          stands.  Posix.2 says the behaviour is marked as obsolescent. */
  337.       else
  338.         {
  339.           change_flag_char ('x', '+');
  340.           change_flag_char ('v', '+');
  341.         }
  342.  
  343.       break;
  344.     }
  345.  
  346.       if ((on_or_off = *string) &&
  347.       (on_or_off == '-' || on_or_off == '+'))
  348.     {
  349.       int i = 1;
  350.       while (flag_name = string[i++])
  351.         {
  352.           if (flag_name == '?')
  353.         {
  354.           /* Print all the possible flags. */
  355.         }
  356.           else if (flag_name == 'o') /* -+o option-name */
  357.         {
  358.           char *option_name;
  359.           WORD_LIST *opt;
  360.  
  361.           opt = list->next;
  362.  
  363.           if (!opt)
  364.             {
  365.               list_long_opts ();
  366.               continue;
  367.             }
  368.  
  369.           option_name = opt->word->word;
  370.  
  371.           if (!option_name || !*option_name || (*option_name == '-'))
  372.             {
  373.               list_long_opts ();
  374.               continue;
  375.             }
  376.           list = list->next; /* Skip over option name. */
  377.  
  378.           if (set_minus_o_option
  379.               (on_or_off, option_name) != EXECUTION_SUCCESS)
  380.             return (EXECUTION_FAILURE);
  381.         }
  382.           else
  383.         {
  384.           if (change_flag_char (flag_name, on_or_off) == FLAG_ERROR)
  385.             {
  386.               char opt[3];
  387.               opt[0] = on_or_off;
  388.               opt[1] = flag_name;
  389.               opt[2] = '\0';
  390.               bad_option (opt);
  391.               return (EXECUTION_FAILURE);
  392.             }
  393.         }
  394.         }
  395.     }
  396.       else
  397.     {
  398.       break;
  399.     }
  400.       list = list->next;
  401.     }
  402.  
  403.   /* Assigning $1 ... $n */
  404.   if (list || force_assignment)
  405.     remember_args (list, 1);
  406.   return (EXECUTION_SUCCESS);
  407. }
  408.  
  409. $BUILTIN unset
  410. $FUNCTION unset_builtin
  411. $SHORT_DOC unset [-f] [-v] [name ...]
  412. For each NAME, remove the corresponding variable or function.  Given
  413. the `-v', unset will only act on variables.  Given the `-f' flag,
  414. unset will only act on functions.  With neither flag, unset first
  415. tries to unset a variable, and if that fails, then tries to unset a
  416. function.  Some variables (such as PATH and IFS) cannot be unset; also
  417. see readonly.
  418. $END
  419.  
  420. unset_builtin (list)
  421.   WORD_LIST *list;
  422. {
  423.   extern char **non_unsettable_vars;
  424.   int unset_function = 0, unset_variable = 0;
  425.   int any_failed = 0;
  426.   char *name;
  427.  
  428.   while (list)
  429.     {
  430.       name = list->word->word;
  431.  
  432.       if (strcmp (name, "-f") == 0)
  433.     {
  434.       list = list->next;
  435.       unset_function++;
  436.       continue;
  437.     }
  438.  
  439.       if (strcmp (name, "-v") == 0)
  440.     {
  441.       list = list->next;
  442.       unset_variable++;
  443.       continue;
  444.     }
  445.       else if (strcmp (name, "--") == 0)
  446.     {
  447.       list = list->next;
  448.       break;
  449.     }
  450.       else if (*name == '-')
  451.     {
  452.       bad_option (name);
  453.       return (EXECUTION_FAILURE);
  454.     }
  455.       else
  456.     break;
  457.     }
  458.  
  459.   if (unset_function && unset_variable)
  460.     {
  461.       builtin_error ("cannot simultaneously unset a function and a variable");
  462.       return (EXECUTION_FAILURE);
  463.     }
  464.  
  465.   while (list)
  466.     {
  467.       name = list->word->word;
  468.  
  469.       if (!unset_function &&
  470.       find_name_in_list (name, non_unsettable_vars) > -1)
  471.     {
  472.       builtin_error ("%s: cannot unset", name);
  473.       any_failed++;
  474.     }
  475.       else
  476.     {
  477.       /* Unless the -f option is supplied, the name refers to a
  478.          variable. */
  479.       int tem = makunbound (name,
  480.           unset_function ? shell_functions : shell_variables);
  481.  
  482.       /* This is what Posix.2 draft 11+ says.  ``If neither -f nor -v
  483.          is specified, the name refers to a variable; if a variable by
  484.          that name does not exist, a function by that name, if any,
  485.          shall be unset.'' */
  486.       if ((tem == -1) && !unset_function && !unset_variable)
  487.         tem = makunbound (name, shell_functions);
  488.  
  489.       if (tem == -1)
  490.         any_failed++;
  491.       else if (!unset_function)
  492.         stupidly_hack_special_variables (name);
  493.     }
  494.       list = list->next;
  495.     }
  496.  
  497.   if (any_failed)
  498.     return (EXECUTION_FAILURE);
  499.   else
  500.     return (EXECUTION_SUCCESS);
  501. }
  502.